#ifndef prs_FrmBuildControl_H
#define prs_FrmBuildControl_H

#include "prs_FrmUseTemplate.h"
#include "prs_FrmPanelStyle.h"
#include "prs_FrmPanel.h"
#include "prs_FrmImageStyle.h"
#include "prs_FrmImage.h"
#include "prs_FrmStringStyle.h"
#include "prs_FrmString.h"
#include "prs_FrmIntegerStyle.h"
#include "prs_FrmInteger.h"
#include "prs_FrmDoubleStyle.h"
#include "prs_FrmDouble.h"
#include "prs_FrmDateStyle.h"
#include "prs_FrmDate.h"
#include "prs_FrmButtonStyle.h"
#include "prs_FrmButton.h"
#include "prs_FrmLineStyle.h"
#include "prs_FrmLine.h"
#include "prs_FrmParaStyle.h"
#include "prs_FrmPara.h"
#include "prs_FrmParaEditStyle.h"
#include "prs_FrmParaEdit.h"
#include "prs_FrmColStyle.h"
#include "prs_FrmCol.h"
#include "prs_FrmRowStyle.h"
#include "prs_FrmRow.h"
#include "prs_FrmTableStyle.h"
#include "prs_FrmTable.h"
#include "prs_FrmSplitterStyle.h"
#include "prs_FrmSplitter.h"
#include "prs_FrmFrameStyle.h"
#include "prs_FrmFrame.h"
#include "prs_FrmPageControlStyle.h"
#include "prs_FrmPageControl.h"
#include "prs_FrmScinPanel.h"
#include "prs_Form.h"

namespace prs {

///////////////////////////////////////////////////////////////////////////////

struct TFrmBuildControl 
:public svl::IVisitor<TNodeForm>
,public svl::IVisitor<TNodeUseTemplate>
,public svl::IVisitor<TNodeUseTemplateBody>
,public svl::IVisitor<TFrmControlsValue>

,public svl::IVisitor<TNodeFrmString>
,public svl::IVisitor<TNodeFrmInteger>
,public svl::IVisitor<TNodeFrmDouble>
,public svl::IVisitor<TNodeFrmDate>
,public svl::IVisitor<TNodeFrmPanel>
,public svl::IVisitor<TNodeFrmImage>
,public svl::IVisitor<TNodeFrmButton>
,public svl::IVisitor<TNodeFrmLine>
,public svl::IVisitor<TNodeFrmPara>
,public svl::IVisitor<TNodeFrmParaEdit>
,public svl::IVisitor<TNodeFrmCol>

,public svl::IVisitor<TNodeFrmRow>
,public svl::IVisitor<TNodeFrmRowCaption>
,public svl::IVisitor<TNodeFrmRowChildren>
,public svl::IVisitor<TNodeFrmRowExpand>

,public svl::IVisitor<TNodeFrmTable>
,public svl::IVisitor<TNodeFrmTableCaption>
,public svl::IVisitor<TNodeFrmTableGrid>

,public svl::IVisitor<TNodeFrmVSplitter>
,public svl::IVisitor<TNodeFrmHSplitter>

,public svl::IVisitor<TNodeFrmFrame>
,public svl::IVisitor<TNodeFrmFrameClient>

,public svl::IVisitor<TNodeFrmPageButton>
,public svl::IVisitor<TNodeFrmPageControl>
,public svl::IVisitor<TNodeFrmPage>

,public svl::IVisitor<TNodeFrmScinPanel>
{
  enum EAdd {
    EAdd_First,
    EAdd_Last,
    EAdd_Before,
    EAdd_After
  }
  Add;
  frm::control::TPanel *CurrentControl;
  //
  TFrmBuildControl(frm::control::TPanel *ParentControl) { 
    parentControl = ParentControl; 
    parentRow = NULL;
    Add = EAdd_Last;
    CurrentControl = NULL;

    //parentStyle = NULL; 
  }
  TFrmBuildControl(TFrmBuildControl &V) { *this = V;}
  //
  void operator = (TFrmBuildControl &From) { 
    parentControl = From.parentControl; 
    parentRow = From.parentRow;
    Add = From.Add;
    CurrentControl = From.CurrentControl;

    //parentStyle = From.parentStyle; 
  }
  //
  void Visit(TNodeForm &Node);
  
  void Visit(TNodeFrmString   &Node);
  void Visit(TNodeFrmInteger  &Node);
  void Visit(TNodeFrmDouble   &Node);
  void Visit(TNodeFrmDate     &Node);
  void Visit(TNodeFrmPanel    &Node);
  void Visit(TNodeFrmImage    &Node);
  void Visit(TNodeFrmButton   &Node);
  void Visit(TNodeFrmLine     &Node);
  void Visit(TNodeFrmPara     &Node);
  void Visit(TNodeFrmParaEdit &Node);
  void Visit(TNodeFrmCol      &Node);
  //
  void Visit(TNodeFrmRow         &Node);
  void Visit(TNodeFrmRowCaption  &Node);
  void Visit(TNodeFrmRowChildren &Node);
  void Visit(TNodeFrmRowExpand   &Node);
  //
  void Visit(TNodeFrmTable        &Node);
  void Visit(TNodeFrmTableCaption &Node);
  void Visit(TNodeFrmTableGrid    &Node);
  //
  void Visit(TNodeFrmVSplitter &Node);
  void Visit(TNodeFrmHSplitter &Node);
  //
  void Visit(TNodeFrmPageButton  &Node);
  void Visit(TNodeFrmPageControl &Node);
  void Visit(TNodeFrmPage		 &Node);
  //
  void Visit(TNodeFrmFrame       &Node);
  void Visit(TNodeFrmFrameClient &Node);
  //
  void Visit(TNodeFrmScinPanel &Node);
  //
  void Visit(TNodeUseTemplate      &Node) { Node.AcceptChildren(*this);}
  void Visit(TNodeUseTemplateBody  &Node) { Node.AcceptChildren(*this);}
  void Visit(TFrmControlsValue     &Node) { Node.AcceptChildren(*this);}

private:
  static void addControl(
    TFrmBuildControl &Param,
    frm::control::TPanel *Control
  );
  //
  frm::control::TPanel *parentControl;
  //TNodeStyle           *parentStyle;
  frm::control::TRow   *parentRow;
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////
}

#endif
